<?php

namespace StarCloud\Library;

use Phalcon\Di;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Sts\Sts;
use StarCloud\Models\StarCloud\VideoLibrary;

use AlibabaCloud\SDK\ICE\V20201109\ICE;
use AlibabaCloud\SDK\ICE\V20201109\Models\SubmitMediaProducingJobRequest;
use Darabonba\OpenApi\Models\Config;

/**
 * 阿里云视频点播服务
 * Class AliyunStsClient
 * @package StarCloud\Library
 */
class AliyunStsClient
{
    private $accessKeyId = 'LTAI5tNADeAAtcmPDMUm1CdS';
    private $accessKeySecret = 'SToJ2y3HoafWpm5qWxgteLDUhABMBV';
    private $roleArn = 'acs:ram::1074038102267229:role/voderole';
    private $roleSessionName = 'voderole';
    private $templateGroupId = '73cbd624d5266dc65b10dde9af1b6ece';
    private $kmsKeyId = 'fc1d6478-7656-4413-be5b-cc3cd52f26e9';
    private $decryptUrl = 'https://www.sdgjxy.com/api/video_library/decrypt';
    public static $instance;

    private function __construct()
    {
        $config = Di::getDefault()->get('config')['aliyun_sts'];
        isset($config['accessKeyId']) && $this->accessKeyId = $config['accessKeyId'];
        isset($config['accessKeySecret']) && $this->accessKeySecret = $config['accessKeySecret'];
        isset($config['roleArn']) && $this->roleArn = $config['roleArn'];
        isset($config['roleSessionName']) && $this->roleSessionName = $config['roleSessionName'];
        isset($config['templateGroupId']) && $this->templateGroupId = $config['templateGroupId'];
        isset($config['kmsKeyId']) && $this->kmsKeyId = $config['kmsKeyId'];
        isset($config['decryptUrl']) && $this->decryptUrl = $config['decryptUrl'];

        AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
            ->regionId('cn-shanghai')
            ->asDefaultClient();
    }

    public static function getInstanceClient()
    {
        if (empty(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * 客户端获取token
     * @return mixed
     */
    public function getToken()
    {
        $result = Sts::v20150401()
            ->assumeRole()
            //指定角色ARN
            ->withRoleArn($this->roleArn)
            //RoleSessionName即临时身份的会话名称，用于区分不同的临时身份
            ->withRoleSessionName($this->roleSessionName)
            //设置权限策略以进一步限制角色的权限
            //以下权限策略表示拥有所有OSS的只读权限
            ->withPolicy('{
             "Statement":[
                {
                     "Action":
                 [
                     "oss:Get*",
                     "oss:List*",
                     "vod:CreateUploadVideo",
                     "vod:RefreshUploadVideo",
                     "vod:CreateUploadImage"
                     ],
                      "Effect": "Allow",
                      "Resource": "*"
                }
                   ],
          "Version": "1"
        }')
            ->connectTimeout(60)
            ->timeout(65)
            ->request();

        $videoData = $result->toArray();

        return $videoData;
    }

    /**
     * 上传成功阿里云回调->提交转码、标准加密
     * @param $data
     * @param int $create_uid
     * @return bool|string
     * @throws SentryException
     */
    public function submitTranscodeJobs($data, $create_uid = 0)
    {
        $data = json_decode($data, true);
        if (!isset($data['VideoId'])) {
            return "fail";
        }

        //加片头逻辑
        $info = $this->getMezzanineInfo($data['VideoId'], true);
        $file_name = $info['Mezzanine']['FileName'] ?? '';
        $video = VideoLibrary::getVideo($data['VideoId']);
//        if ($video->getHeaderStatus() == VideoLibrary::HEADER_STATUS_NO) {
//            $this->videoMerge($video);
//            return 'success';
//        }

        //上传完成事件，提交转码加密作业
        if (isset($data['EventType']) && $data['EventType'] == "FileUploadComplete") {
            if ($data['Status'] == "success") {
                $kmsKey = self::generateDataKey();
                $encryptConfig = [];
                # 解密接口地址 视频播放时会访问这里，可以在这里获取密文并使用下边的解密函数去解密
                $encryptConfig["DecryptKeyUri"] = $this->decryptUrl . "?key=" . $kmsKey['CiphertextBlob'];
                //秘钥服务的类型，目前只支持KMS
                $encryptConfig["KeyServiceType"] = "KMS";
                # Ciphertext作为解密接口的参数名称，可自定义，此处只作为参考
                $encryptConfig["CipherText"] = $kmsKey['CiphertextBlob'];
                $encryptConfig = json_encode($encryptConfig);
                $result = AlibabaCloud::rpc()
                    ->product('vod')
                    ->scheme('https')// https | http
                    ->version('2017-03-21')
                    ->action('SubmitTranscodeJobs')
                    ->method('POST')
                    ->host('vod.cn-shanghai.aliyuncs.com')
                    ->options([
                        'query' => [
                            'RegionId' => "cn-shanghai",
                            'TemplateGroupId' => $this->templateGroupId,
                            'VideoId' => $data['VideoId'],
                            'EncryptConfig' => $encryptConfig,
                        ],
                    ])
                    ->request();
                Di::getDefault()->get('logger')->info(date("H:i:s") . "点播（已提交转码加密）：" . json_encode($data));
                return "success";
            }
        }
        //转码完成事件，更新封面、时长、大小信息
        if (isset($data['EventType']) && $data['EventType'] == "StreamTranscodeComplete") {
            if ($data['Status'] == "success") {
                //去查询video信息，并对信息进行入库处理
                $result = AlibabaCloud::rpc()
                    ->product('vod')
                    ->version('2017-03-21')
                    ->action('GetVideoInfo')
                    ->method('POST')
                    ->host('vod.cn-shanghai.aliyuncs.com')
                    ->options([
                        'query' => [
                            'RegionId' => "cn-shanghai",
                            'VideoId' => $data['VideoId'],
                        ],
                    ])
                    ->request();
                $videoData = $result->toArray();
                if (!isset($videoData['Video'])) {
                    return false;
                }
                $tempVideo = $videoData['Video'];
                //更新library表
                $videoLibrary = [
                    'name' => $tempVideo['Title'],
                    'image' => isset($tempVideo['CoverURL']) ? $tempVideo['CoverURL'] : "",
                    'video_id' => $tempVideo['VideoId'],
                    'original_link' => '',
                    'duration' => intval(isset($tempVideo['Duration']) ? $tempVideo['Duration'] : ""),
                    'size' => isset($tempVideo['Size']) ? $tempVideo['Size'] : ""
                ];
                /* @var $checkLibrary VideoLibrary */
                $checkLibrary = VideoLibrary::findFirstByVideoId($tempVideo['VideoId']);
                if (!empty($checkLibrary)) {
                    $checkLibrary->editVideoLibrary($videoLibrary);
                } else {
                    VideoLibrary::newVideoLibrary($videoLibrary['name'], $videoLibrary['image'], $videoLibrary['video_id'], $videoLibrary['original_link'], $videoLibrary['duration'], $videoLibrary['size'], $create_uid);
                }
                Di::getDefault()->get('logger')->info(date("H:i:s") . "点播（视频信息已入库）：" . json_encode($videoData));
            }
            return "success";
        }
    }

    /**
     * 生产加密密钥
     * @return mixed
     */
    public function generateDataKey()
    {
        AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
            ->regionId('cn-shanghai')
            ->asDefaultClient();
        try {
            $result = AlibabaCloud::rpc()
                ->product('Kms')
                ->scheme('https')// https | http
                ->version('2016-01-20')
                ->action('GenerateDataKey')
                ->method('POST')
                ->host('kms.cn-shanghai.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => "cn-shanghai",
                        'KeyId' => $this->kmsKeyId,
                        'KeySpec' => "AES_128",
                    ],
                ])
                ->request();
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
        return $result->toArray();
    }

    /**
     * 视频播放解密
     * @param $key
     * @return bool|string
     */
    public function decrypt($key)
    {
        header("Access-Control-Allow-Origin:*");
        header("Access-Control-Allow-Methods:GET, POST, OPTIONS, DELETE");
        header("Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding");
        try {
            $result = AlibabaCloud::rpc()
                ->product('Kms')
                ->scheme('https')// https | http
                ->version('2016-01-20')
                ->action('Decrypt')
                ->method('POST')
                ->host('kms.cn-shanghai.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => "cn-shanghai",
                        'CiphertextBlob' => $key,
                    ],
                ])
                ->request();
        } catch (ClientException $e) {
            echo $e->getErrorMessage() . PHP_EOL;
        } catch (ServerException $e) {
            echo $e->getErrorMessage() . PHP_EOL;
        }
        return base64_decode($result->toArray()['Plaintext']);
    }

    /**
     * 获取视频源信息
     * @param string $videoId
     * @param bool $returnAll
     * @return string
     */
    public function getMezzanineInfo($videoId = "", $returnAll = false)
    {
        $result = AlibabaCloud::rpc()
            ->product('vod')
            ->version('2017-03-21')
            ->action('GetMezzanineInfo')
            ->method('GET')
            ->host('vod.cn-shanghai.aliyuncs.com')
            ->options([
                'query' => [
                    'VideoId' => $videoId
                ],
            ])
            ->request();
        $resp = $result->toArray();
        Di::getDefault()->get('logger')->info(date("H:i:s") . "点播（视频源信息）：" . json_encode($resp));
        if ($returnAll) {
            return $resp;
        }
        if (isset($resp['Mezzanine']['FileURL'])) {
            return $resp['Mezzanine']['FileURL'];
        } else {
            return "";
        }
    }

    /**
     * 搜索视频文件信息
     * @param string $videoId
     * @return mixed
     */
    public function searchMedia($videoId = "")
    {
        $result = AlibabaCloud::rpc()
            ->product('vod')
            ->version('2017-03-21')
            ->action('SearchMedia')
            ->method('GET')
            ->host('vod.cn-shanghai.aliyuncs.com')
            ->options([
                'query' => [
                    'SearchType' => 'video',
                    'Fields' => 'CoverUrl',
                    'Match' => "VideoId='{$videoId}'"
                ],
            ])
            ->request();
        $resp = $result->toArray();
        return $resp;
    }

    /**
     * 获取阿里云播放器配置
     * @param string $video_id
     * @return array
     */
    public function aliPlayer($video_id = '')
    {
        if (empty($video_id)) {
            return [];
        }
        try {
            $result = AlibabaCloud::rpc()
                ->product('vod')
                ->scheme('https')// https | http
                ->version('2017-03-21')
                ->action('GetVideoPlayAuth')
                ->method('POST')
                ->host('vod.cn-shanghai.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => "cn-shanghai",
                        'VideoId' => $video_id,
                    ],
                ])
                ->request();
            $result = $result->toArray();
        } catch (\Exception $e) {
            echo $e->getMessage();
            die;
        }

        return $result;
    }

    /**
     * 提交片头合成任务
     * @param VideoLibrary $videoLibrary
     * @return bool
     */
    public function videoMerge(VideoLibrary $videoLibrary)
    {
        return;
        $media_id = $videoLibrary->getVideoId();
        var_dump($media_id);
        try {
            //获取原视频信息
            $info = $this->getMezzanineInfo($media_id, true);
            $file_name = $info['Mezzanine']['FileName'] ?? '';
            $cover_url = $info['Mezzanine']['CoverUrl'] ?? '';

            //初始化任务配置
            $config = new Config();
            $config->accessKeyId = $this->accessKeyId;
            $config->accessKeySecret = $this->accessKeySecret;
            $config->regionId = "cn-shanghai";
            $config->endpoint = "ice.cn-shanghai.aliyuncs.com";
            $client = new ICE($config);

            //通过timeline创建合成任务
            $request = new SubmitMediaProducingJobRequest();
            $request->projectId = "004231b0d178465ca885f46ec8f39555";
            $request->timeline = "{\"VideoTracks\":[{\"VideoTrackClips\":[{\"MediaId\":\"481accb46716483a955f73e0ad3cb5f0\"},{\"MediaId\":\"$media_id\"}]}]}";
            $request->outputMediaTarget = "vod-media";
            $request->outputMediaConfig = "{\"StorageLocation\":\"outin-192add0992e811eca06300163e1c94a4.oss-cn-shanghai.aliyuncs.com\",\"FileName\":\"$file_name\",\"VodTemplateGroupId\":\"VOD_NO_TRANSCODE\"}";
            $request->projectMetadata = "{\"coverURL\":\"$cover_url\"}";
            $response = $client->submitMediaProducingJob($request);

            $videoLibrary->setOriginVideoId($response->body->vodMediaId, $media_id);

            Di::getDefault()->get('logger')->info(date("H:i:s") . "点播（已提交片头合成任务）：" . $response->body->vodMediaId);

            return true;
        } catch (\Exception $e) {
            var_dump($e->getMessage());
            $videoLibrary->headerStatusYes();
        }
    }
}
